// NOWHINE NC009 <- Shared file with system team so uses non-CamX file naming
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2017-2018 Qualcomm Technologies, Inc.
// All Rights Reserved.
// Confidential and Proprietary - Qualcomm Technologies, Inc.
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @file  tf10setting.cpp
/// @brief tf10 IQ setting calculation
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#include "NcLibWarp.h"
#include "tf10setting.h"

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// TF10Setting::CalculateHWSetting
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
BOOL TF10Setting::CalculateHWSetting(
    const TF10InputData*                                pInput,
    tf_1_0_0::mod_tf10_cct_dataType::cct_dataStruct*    pData,
    tf_1_0_0::chromatix_tf10_reserveType*               pReserveData,
    tf_1_0_0::chromatix_tf10Type::enable_sectionStruct* pModuleEnable,
    VOID*                                               pOutput)
{
    BOOL result = TRUE;

    if ((NULL != pInput) && (NULL != pData) && (NULL != pOutput))
    {
        TF10UnpackedField*    pUnpackedField  = static_cast<TF10UnpackedField*>(pOutput);
        RefinementParameters* pFwRefineParams = static_cast<RefinementParameters*>(pInput->pRefinementParameters);
        TfParameters*         pFwTFParams     = static_cast<TfParameters*>(pInput->pTFParameters);
        TF_REG*               pRegPass        = pUnpackedField->regTF10Data;
        TF_Chromatix*         pTFChromatix    = static_cast<TF_Chromatix*>(pInput->pNCChromatix);
        NCLIB_CONTEXT_TF      nclibContext    = {0};

        RefinementPassParameters* pFwStructRefinement = &(pFwRefineParams->dc[0]);
        TfPassParameters*         pFwStructTf         = &(pFwTFParams->parameters[0]);

        CAMX_ASSERT(pInput->maxUsedPasses <= PASS_NAME_MAX);
        CAMX_ASSERT(NULL != pFwStructRefinement);
        CAMX_ASSERT(NULL != pFwStructTf);

        IQSettingUtils::Memset(pFwStructTf, 0, sizeof(TfPassParameters) * PASS_NAME_MAX);
        IQSettingUtils::Memset(pFwStructRefinement, 0, sizeof(RefinementPassParameters) * (PASS_NAME_MAX - 1));
        IQSettingUtils::Memset(pTFChromatix, 0, sizeof(TF_Chromatix)*PASS_NAME_MAX);
        IQSettingUtils::Memset(pRegPass, 0, sizeof(TF_REG)*PASS_NAME_MAX);

        pUnpackedField->enable = static_cast<UINT16>(pModuleEnable->master_en);
        for (UINT32 passType = 0; passType < pInput->maxUsedPasses; passType++)
        {
            pTFChromatix[passType].master_en = pUnpackedField->enable;
            // This change is only there until we get separate chromatix for Preview and Snapshot
            if (pInput->useCase == CONFIG_VIDEO)
            {
                pReserveData->mod_tf10_pass_reserve_data[passType].pass_data.is_anr_strength_blender_mode = 0;
            }
        }
        MapChromatix2TFChromatix(pReserveData->mod_tf10_pass_reserve_data,
                                 pData,
                                 pInput->maxUsedPasses,
                                 pTFChromatix);

        nclibContext.fullPassIcaOutputFrameWidth  = pInput->fullPassIcaOutputFrameWidth;
        nclibContext.fullPassIcaOutputFrameHeight = pInput->fullPassIcaOutputFrameHeight;
        nclibContext.frameNumber                  = pInput->mfnrFrameNum;
        nclibContext.numberOfFrames               = pInput->numOfFrames;
        nclibContext.tfHasReferenceInput          = pInput->hasTFRefInput;
        nclibContext.upscalingFactorMFSR_ICA      = pInput->upscalingFactorMFSR;
        nclibContext.preferPaddingByReflection    = 0;
        nclibContext.isDigitalZoomEnabled         = pInput->isDigitalZoomEnabled;

        if (nclibContext.isDigitalZoomEnabled)
        {
            UINT32 frameWidth  = ((static_cast<UINT32>(static_cast<FLOAT>(nclibContext.fullPassIcaOutputFrameWidth) *
                nclibContext.upscalingFactorMFSR_ICA) + 1) >> 1) << 1;  // make it even
            UINT32 frameHeight = ((static_cast<UINT32>(static_cast<FLOAT>(nclibContext.fullPassIcaOutputFrameHeight) *
                nclibContext.upscalingFactorMFSR_ICA) + 1) >> 1) << 1;  // make it even

            nclibContext.dzStartX                  = pInput->digitalZoomStartX;
            nclibContext.dzStartY                  = pInput->digitalZoomStartY;
            nclibContext.dzSizeX                   = frameWidth;
            nclibContext.dzSizeY                   = frameHeight;
            nclibContext.preferPaddingByReflection = 1;
        }

        if (pInput->useCase == CONFIG_VIDEO)
        {
            nclibContext.tfConfigOption = IPE_CONFIG_VIDEO;
        }
        else if (pInput->useCase == CONFIG_STILL)
        {
            // MF_CONFIG_NONE / MF_CONFIG_POSTPROCESS
            nclibContext.tfConfigOption = IPE_CONFIG_STILL;
            if (pInput->configMF == MF_CONFIG_PREFILT)
            {
                nclibContext.tfHasReferenceInput = 0;
                nclibContext.tfConfigOption      = IPE_CONFIG_MF_PRE;
                nclibContext.numberOfFrames      = pInput->numOfFrames;
            }
            else if (pInput->configMF == MF_CONFIG_TEMPORAL)
            {
                nclibContext.tfHasReferenceInput = 1;
                nclibContext.numberOfFrames      = pInput->numOfFrames;
                nclibContext.tfConfigOption      = IPE_CONFIG_MF_TEMPORAL;
            }
        }
        else
        {
            /// @todo (CAMX-1812) Need to add logging for Common library
            CAMX_LOG_ERROR(CamxLogGroupPProc, "Input use case %d not supported", pInput->useCase);
            result = FALSE;
        }
        CAMX_LOG_VERBOSE(CamxLogGroupPProc, "  ref input %d", nclibContext.tfHasReferenceInput);
        if (TRUE == result)
        {
            // Per Pass Configurations
            for (UINT32 passType = 0; passType < pInput->maxUsedPasses; passType++)
            {
                TF_Chromatix* pCurrentChromatix = &pTFChromatix[passType];
                RefinementPassParameters* pRefinementPassParams = NULL;
                if (passType > 0)
                {
                    pRefinementPassParams = &pFwStructRefinement[passType - 1];
                }
                /* INT32 validateRes = Validate_TF_Chromatix(pCurrentChromatix);
                if (0 != validateRes)
                {
                    /// @todo (CAMX-1812) Need to add logging for Common library
                    CAMX_LOG_WARN(CamxLogGroupPProc, "Chromatix validation, number of invalid paramters: %d", validateRes);
                    result = FALSE;
                    break;
                } */
                UINT32 curPassScalingRatioLog4 = 0;
                if (passType == PASS_TYPE_FULL)
                {
                    curPassScalingRatioLog4 = 0;
                }
                else if (passType == PASS_TYPE_DC4)
                {
                    curPassScalingRatioLog4 = 1;
                }
                else if (passType == PASS_TYPE_DC16)
                {
                    curPassScalingRatioLog4 = 2;
                }
                else if (passType == PASS_TYPE_DC64)
                {
                    curPassScalingRatioLog4 = 3;
                }
                else
                {
                    /// @todo (CAMX-1812) Need to add logging for Common library
                    CAMX_LOG_WARN(CamxLogGroupPProc, "passType %d not supported", passType);
                    result = FALSE;
                    break;
                }

                result = TF_ProcessNcLib(pCurrentChromatix,
                                         nclibContext.tfConfigOption,
                                         curPassScalingRatioLog4,
                                         &pRegPass[passType],
                                         &pFwStructTf[passType],
                                         pRefinementPassParams);
                if (NCLIB_FALSE == result)
                {
                    /// @todo (CAMX-1812) Need to add logging for Common library
                    CAMX_LOG_WARN(CamxLogGroupPProc, "TF_ProcessNcLib failed");
                    break;
                }

                result = TF_ConcludeFrameLevelRegistersConfiguration(pCurrentChromatix,
                                                                     &nclibContext,
                                                                     curPassScalingRatioLog4,
                                                                     pInput->maxUsedPasses,
                                                                     &pRegPass[passType],
                                                                     pRefinementPassParams,
                                                                     &pFwStructTf[passType]);
                if (NCLIB_FALSE == result)
                {
                    /// @todo (CAMX-1812) Need to add logging for Common library
                    CAMX_LOG_WARN(CamxLogGroupPProc, "TF_ConcludeFrameLevelRegistersConfiguration failed");
                    break;
                }

                if (NULL != pInput->pWarpGeometriesOutput)
                {
                    // Override the lnr opt center x / y coordinates with Warp Geometries Output
                    NcLibWarpGeomOut* pWarpDataOutput   = static_cast<NcLibWarpGeomOut*>(pInput->pWarpGeometriesOutput);
                    pCurrentChromatix->lnr_opt_center_x = pWarpDataOutput->tf_lnr_opt_center_x;
                    pCurrentChromatix->lnr_opt_center_y = pWarpDataOutput->tf_lnr_opt_center_y;
                }
                result = TF_CalcWarpDependedParams(pCurrentChromatix,
                                                   &nclibContext,
                                                   curPassScalingRatioLog4,
                                                   &pRegPass[passType],
                                                   &pFwStructTf[passType]);
                if (NCLIB_FALSE == result)
                {
                    /// @todo (CAMX-1812) Need to add logging for Common library
                    CAMX_LOG_WARN(CamxLogGroupPProc, "TF_CalcWarpDependedParams failed");
                    break;
                }

                CopyTFFwParamsToPcsimRegs(&pFwStructTf[passType],
                                          pRefinementPassParams,
                                          &pRegPass[passType],
                                          passType,
                                          nclibContext.tfConfigOption);

                /* if (TRUE == pRegPass[passType].en)
                {
                    validateRes = Validate_TF_REG(&pRegPass[passType]);
                    if (0 != validateRes)
                    {
                        /// @todo (CAMX-1812) Need to add logging for Common library
                        CAMX_LOG_WARN(CamxLogGroupPProc, "passType=%d regs validation failed %d", passType, validateRes);
                    }

                    if (NCLIB_FALSE == ValidateTfCalc(&pFwStructTf[passType], pRefinementPassParams, curPassScalingRatioLog4))
                    {
                        /// @todo (CAMX-1812) Need to add logging for Common library
                        CAMX_LOG_WARN(CamxLogGroupPProc, "passType=%d ValidateTfCalc failed", passType);
                    }
                } */
            }
        }
    }
    else
    {
        /// @todo (CAMX-1812) Need to add logging for Common library
        CAMX_LOG_ERROR(CamxLogGroupPProc, "pInput=%p, pData=%p, pOutput=%p", pInput, pData, pOutput);
        result = FALSE;
    }

    return result;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// TF10Setting::MapChromatix2TFChromatix
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
VOID TF10Setting::MapChromatix2TFChromatix(
    tf_1_0_0::mod_tf10_pass_reserve_dataType*        pReserveData,
    tf_1_0_0::mod_tf10_cct_dataType::cct_dataStruct* pUnpackedData,
    UINT32                                           passNumMax,
    TF_Chromatix*                                    pTFChromatix)
{
    TF_Chromatix*                                              pPassTFChromatix;
    tf_1_0_0::tf10_rgn_dataType*                               pPassUnpackedData;
    tf_1_0_0::mod_tf10_pass_reserve_dataType::pass_dataStruct* pPassReserveData;

    UINT32    idx;
    UINT32    passType;

    for (passType = 0; passType < passNumMax; passType++)
    {
        pPassTFChromatix  = &pTFChromatix[passType];
        pPassUnpackedData = &pUnpackedData->mod_tf10_pass_data[passType].tf10_rgn_data;
        pPassReserveData  = &pReserveData[passType].pass_data;

        pPassTFChromatix->en                                      = static_cast<UINT>(pPassUnpackedData->en);
        pPassTFChromatix->scene_cut_recovery_time                 =
            static_cast<PARAM_UINT>(pPassUnpackedData->scene_cut_recovery_time);
        pPassTFChromatix->video_first_frame_spatial_nr_percentage =
            static_cast<PARAM_UINT>(pPassUnpackedData->video_first_frame_spatial_nr_percentage);
        pPassTFChromatix->smear_inputs_for_decisions              =
             pPassReserveData->smear_inputs_for_decisions;
        pPassTFChromatix->enable_noise_est_by_luma                = pPassReserveData->enable_noise_est_by_luma;
        pPassTFChromatix->enable_noise_est_by_chroma              = pPassReserveData->enable_noise_est_by_chroma;
        pPassTFChromatix->indications_premultiply_factor          = pPassReserveData->indications_premultiply_factor;
        pPassTFChromatix->invert_temporal_blending_weights        = pPassReserveData->invert_temporal_blending_weights;
        pPassTFChromatix->blending_mode                           = pPassReserveData->blending_mode;
        pPassTFChromatix->constant_blending_factor_y              =
            static_cast<PARAM_UINT>(IQSettingUtils::RoundFLOAT(pPassUnpackedData->constant_blending_factor_y));
        pPassTFChromatix->constant_blending_factor_c              =
            static_cast<PARAM_UINT>(IQSettingUtils::RoundFLOAT(pPassUnpackedData->constant_blending_factor_c));
        pPassTFChromatix->enable_lnr                              = pPassReserveData->enable_lnr;
        pPassTFChromatix->use_indications                         =
            static_cast<PARAM_UINT>(IQSettingUtils::RoundFLOAT(pPassUnpackedData->use_indications));
        pPassTFChromatix->disable_luma_ghost_detection            = pPassReserveData->disable_luma_ghost_detection;
        pPassTFChromatix->disable_chroma_ghost_detection          = pPassReserveData->disable_chroma_ghost_detection;
        pPassTFChromatix->use_anr_for_decisions_y                 = pPassReserveData->use_anr_for_decisions_y;
        pPassTFChromatix->use_anr_for_decisions_c                 = pPassReserveData->use_anr_for_decisions_c;
        pPassTFChromatix->padding_by_reflection                   = pPassReserveData->padding_by_reflection;
        pPassTFChromatix->sad_y_calc_mode                         =
            static_cast<PARAM_UINT>(IQSettingUtils::RoundFLOAT(pPassUnpackedData->sad_y_calc_mode));
        pPassTFChromatix->sad_c_calc_mode                         =
            static_cast<PARAM_UINT>(IQSettingUtils::RoundFLOAT(pPassUnpackedData->sad_c_calc_mode));
        pPassTFChromatix->is_dci_mode                             =
            static_cast<PARAM_UINT>(IQSettingUtils::RoundFLOAT(pPassUnpackedData->is_dci_mode));
        pPassTFChromatix->indications_affect_fs_decision_also_directly = static_cast<PARAM_UINT>(
            IQSettingUtils::RoundFLOAT(pPassUnpackedData->indications_affect_fs_decision_also_directly));
        pPassTFChromatix->is_same_blending_for_all_frequencies    =
            static_cast<PARAM_UINT>(IQSettingUtils::RoundFLOAT(pPassUnpackedData->is_same_blending_for_all_frequencies));
        pPassTFChromatix->out_of_frame_pixels_confidence          =
            static_cast<PARAM_UINT>(IQSettingUtils::RoundFLOAT(pPassUnpackedData->out_of_frame_pixels_confidence));
        pPassTFChromatix->apply_fs_rank_filter                    =
            static_cast<PARAM_UINT>(IQSettingUtils::RoundFLOAT(pPassUnpackedData->apply_fs_rank_filter));
        pPassTFChromatix->apply_fs_lpf                            =
            static_cast<PARAM_UINT>(IQSettingUtils::RoundFLOAT(pPassUnpackedData->apply_fs_lpf));
        pPassTFChromatix->dither_y                                =
            static_cast<PARAM_UINT>(IQSettingUtils::RoundFLOAT(pPassUnpackedData->dither_y));
        pPassTFChromatix->dither_cb                               =
            static_cast<PARAM_UINT>(IQSettingUtils::RoundFLOAT(pPassUnpackedData->dither_cb));
        pPassTFChromatix->dither_cr                               =
            static_cast<PARAM_UINT>(IQSettingUtils::RoundFLOAT(pPassUnpackedData->dither_cr));
        pPassTFChromatix->morph_erode_en                          = pPassReserveData->morph_erode_en;
        pPassTFChromatix->morph_erode_size                        =
            static_cast<PARAM_UINT>(IQSettingUtils::RoundFLOAT(pPassUnpackedData->morph_erode_size));
        pPassTFChromatix->morph_dilate_en                         = pPassReserveData->morph_dilate_en;
        pPassTFChromatix->morph_dilate_size                       =
            static_cast<PARAM_UINT>(IQSettingUtils::RoundFLOAT(pPassUnpackedData->morph_dilate_size));
        pPassTFChromatix->tr_enable                               =
            static_cast<PARAM_UINT>(IQSettingUtils::RoundFLOAT(pPassUnpackedData->tr_enable));
        pPassTFChromatix->tr_fs_threshold                         =
            static_cast<PARAM_UINT>(IQSettingUtils::RoundFLOAT(pPassUnpackedData->tr_fs_threshold));
        pPassTFChromatix->tr_dead_zone                            =
            static_cast<PARAM_UINT>(IQSettingUtils::RoundFLOAT(pPassUnpackedData->tr_dead_zone));
        pPassTFChromatix->tr_block_num_x                          =
            static_cast<PARAM_UINT>(IQSettingUtils::RoundFLOAT(pPassUnpackedData->tr_block_num_x));
        pPassTFChromatix->tr_block_num_y                          =
            static_cast<PARAM_UINT>(IQSettingUtils::RoundFLOAT(pPassUnpackedData->tr_block_num_y));
        pPassTFChromatix->lnr_opt_center_x                        =
            static_cast<PARAM_UINT>(IQSettingUtils::RoundFLOAT(pPassUnpackedData->lnr_opt_center_x));
        pPassTFChromatix->lnr_opt_center_y                        =
            static_cast<PARAM_UINT>(IQSettingUtils::RoundFLOAT(pPassUnpackedData->lnr_opt_center_y));
        pPassTFChromatix->lnr_ellipses_bounding_rect_w            =
            static_cast<PARAM_UINT>(IQSettingUtils::RoundFLOAT(pPassUnpackedData->lnr_ellipses_bounding_rect_w));
        pPassTFChromatix->lnr_ellipses_bounding_rect_h            =
            static_cast<PARAM_UINT>(IQSettingUtils::RoundFLOAT(pPassUnpackedData->lnr_ellipses_bounding_rect_h));
        for (idx = 0; idx < 17; idx++)
        {
            pPassTFChromatix->noise_params_y_ytb[idx]  = static_cast<PARAM_UINT>(
                IQSettingUtils::RoundFLOAT(pPassUnpackedData->noise_params_y_ytb_tab.noise_params_y_ytb[idx]));
            pPassTFChromatix->noise_params_cb_ytb[idx] = static_cast<PARAM_UINT>(
                IQSettingUtils::RoundFLOAT(pPassUnpackedData->noise_params_cb_ytb_tab.noise_params_cb_ytb[idx]));
            pPassTFChromatix->noise_params_cr_ytb[idx] = static_cast<PARAM_UINT>(
                IQSettingUtils::RoundFLOAT(pPassUnpackedData->noise_params_cr_ytb_tab.noise_params_cr_ytb[idx]));
        }

        for (idx = 0; idx < 8; idx++)
        {
            pPassTFChromatix->noise_params_y_ctb[idx]  = static_cast<PARAM_UINT>(
                IQSettingUtils::RoundFLOAT(pPassUnpackedData->noise_params_y_ctb_tab.noise_params_y_ctb[idx]));
            pPassTFChromatix->noise_params_cb_ctb[idx] = static_cast<PARAM_UINT>(
                IQSettingUtils::RoundFLOAT(pPassUnpackedData->noise_params_cb_ctb_tab.noise_params_cb_ctb[idx]));
            pPassTFChromatix->noise_params_cr_ctb[idx] = static_cast<PARAM_UINT>(
                IQSettingUtils::RoundFLOAT(pPassUnpackedData->noise_params_cr_ctb_tab.noise_params_cr_ctb[idx]));
        }

        pPassTFChromatix->noise_params_y_uv_limit  = pPassReserveData->noise_params_y_uv_limit;
        pPassTFChromatix->noise_params_cb_uv_limit = pPassReserveData->noise_params_cb_uv_limit;
        pPassTFChromatix->noise_params_cr_uv_limit = pPassReserveData->noise_params_cr_uv_limit;
        pPassTFChromatix->noise_params_y_top_lim   =
            static_cast<PARAM_UINT>(IQSettingUtils::RoundFLOAT(pPassUnpackedData->noise_params_y_top_lim));
        pPassTFChromatix->noise_params_cb_top_lim  =
            static_cast<PARAM_UINT>(IQSettingUtils::RoundFLOAT(pPassUnpackedData->noise_params_cb_top_lim));
        pPassTFChromatix->noise_params_cr_top_lim  =
            static_cast<PARAM_UINT>(IQSettingUtils::RoundFLOAT(pPassUnpackedData->noise_params_cr_top_lim));
        pPassTFChromatix->noise_params_y_bot_lim   =
            static_cast<PARAM_UINT>(IQSettingUtils::RoundFLOAT(pPassUnpackedData->noise_params_y_bot_lim));
        pPassTFChromatix->noise_params_cb_bot_lim  =
            static_cast<PARAM_UINT>(IQSettingUtils::RoundFLOAT(pPassUnpackedData->noise_params_cb_bot_lim));
        pPassTFChromatix->noise_params_cr_bot_lim  =
            static_cast<PARAM_UINT>(IQSettingUtils::RoundFLOAT(pPassUnpackedData->noise_params_cr_bot_lim));

        for (idx = 0; idx < 9; idx++)
        {
            pPassTFChromatix->fs_decision_params_y_c1[idx] = static_cast<PARAM_UINT>(
                IQSettingUtils::RoundFLOAT(pPassUnpackedData->fs_decision_params_y_c1_tab.fs_decision_params_y_c1[idx]));
            pPassTFChromatix->fs_decision_params_y_c2[idx] = static_cast<PARAM_UINT>(
                IQSettingUtils::RoundFLOAT(pPassUnpackedData->fs_decision_params_y_c2_tab.fs_decision_params_y_c2[idx]));
            pPassTFChromatix->fs_decision_params_y_c3[idx] = static_cast<PARAM_UINT>(
                IQSettingUtils::RoundFLOAT(pPassUnpackedData->fs_decision_params_y_c3_tab.fs_decision_params_y_c3[idx]));
            pPassTFChromatix->fs_decision_params_y_c4[idx] = static_cast<PARAM_UINT>(
                IQSettingUtils::RoundFLOAT(pPassUnpackedData->fs_decision_params_y_c4_tab.fs_decision_params_y_c4[idx]));
            pPassTFChromatix->fs_decision_params_c_c1[idx] = static_cast<PARAM_UINT>(
                IQSettingUtils::RoundFLOAT(pPassUnpackedData->fs_decision_params_c_c1_tab.fs_decision_params_c_c1[idx]));
            pPassTFChromatix->fs_decision_params_c_c2[idx] = static_cast<PARAM_UINT>(
                IQSettingUtils::RoundFLOAT(pPassUnpackedData->fs_decision_params_c_c2_tab.fs_decision_params_c_c2[idx]));
            pPassTFChromatix->fs_decision_params_c_c3[idx] = static_cast<PARAM_UINT>(
                IQSettingUtils::RoundFLOAT(pPassUnpackedData->fs_decision_params_c_c3_tab.fs_decision_params_c_c3[idx]));
            pPassTFChromatix->fs_decision_params_c_c4[idx] = static_cast<PARAM_UINT>(
                IQSettingUtils::RoundFLOAT(pPassUnpackedData->fs_decision_params_c_c4_tab.fs_decision_params_c_c4[idx]));
            pPassTFChromatix->fs_to_a1_map_y[idx]          = static_cast<PARAM_UINT>(
                IQSettingUtils::RoundFLOAT(pPassUnpackedData->fs_to_a1_map_y_tab.fs_to_a1_map_y[idx]));
            pPassTFChromatix->fs_to_a1_map_c[idx]          = static_cast<PARAM_UINT>(
                IQSettingUtils::RoundFLOAT(pPassUnpackedData->fs_to_a1_map_c_tab.fs_to_a1_map_c[idx]));
            pPassTFChromatix->fs_to_a4_map_y[idx]          = static_cast<PARAM_UINT>(
                IQSettingUtils::RoundFLOAT(pPassUnpackedData->fs_to_a4_map_y_tab.fs_to_a4_map_y[idx]));
            pPassTFChromatix->fs_to_a4_map_c[idx]          = static_cast<PARAM_UINT>(
                IQSettingUtils::RoundFLOAT(pPassUnpackedData->fs_to_a4_map_c_tab.fs_to_a4_map_c[idx]));
        }

        pPassTFChromatix->fs_decision_params_oof_y_c1 = static_cast<PARAM_UINT>(
            IQSettingUtils::RoundFLOAT(pPassUnpackedData->fs_decision_params_oof_y_c1));
        pPassTFChromatix->fs_decision_params_oof_y_c2 = static_cast<PARAM_UINT>(
            IQSettingUtils::RoundFLOAT(pPassUnpackedData->fs_decision_params_oof_y_c2));
        pPassTFChromatix->fs_decision_params_oof_y_c3 = static_cast<PARAM_UINT>(
            IQSettingUtils::RoundFLOAT(pPassUnpackedData->fs_decision_params_oof_y_c3));
        pPassTFChromatix->fs_decision_params_oof_y_c4 = static_cast<PARAM_UINT>(
            IQSettingUtils::RoundFLOAT(pPassUnpackedData->fs_decision_params_oof_y_c4));
        pPassTFChromatix->fs_decision_params_oof_c_c1 = static_cast<PARAM_UINT>(
            IQSettingUtils::RoundFLOAT(pPassUnpackedData->fs_decision_params_oof_c_c1));
        pPassTFChromatix->fs_decision_params_oof_c_c2 = static_cast<PARAM_UINT>(
            IQSettingUtils::RoundFLOAT(pPassUnpackedData->fs_decision_params_oof_c_c2));
        pPassTFChromatix->fs_decision_params_oof_c_c3 = static_cast<PARAM_UINT>(
            IQSettingUtils::RoundFLOAT(pPassUnpackedData->fs_decision_params_oof_c_c3));
        pPassTFChromatix->fs_decision_params_oof_c_c4 = static_cast<PARAM_UINT>(
            IQSettingUtils::RoundFLOAT(pPassUnpackedData->fs_decision_params_oof_c_c4));
        pPassTFChromatix->a3_t1_scale_y               = static_cast<PARAM_UINT>(
            IQSettingUtils::RoundFLOAT(pPassUnpackedData->a3_t1_scale_y));
        pPassTFChromatix->a3_t1_scale_c               = static_cast<PARAM_UINT>(
            IQSettingUtils::RoundFLOAT(pPassUnpackedData->a3_t1_scale_c));
        pPassTFChromatix->a3_t2_scale_y               = static_cast<PARAM_UINT>(
            IQSettingUtils::RoundFLOAT(pPassUnpackedData->a3_t2_scale_y));
        pPassTFChromatix->a3_t2_scale_c               = static_cast<PARAM_UINT>(
            IQSettingUtils::RoundFLOAT(pPassUnpackedData->a3_t2_scale_c));
        pPassTFChromatix->a3_t1_offs_y                = static_cast<PARAM_UINT>(
            IQSettingUtils::RoundFLOAT(pPassUnpackedData->a3_t1_offs_y));
        pPassTFChromatix->a3_t1_offs_c                = static_cast<PARAM_UINT>(
            IQSettingUtils::RoundFLOAT(pPassUnpackedData->a3_t1_offs_c));
        pPassTFChromatix->a3_t2_offs_y                = static_cast<PARAM_UINT>(
            IQSettingUtils::RoundFLOAT(pPassUnpackedData->a3_t2_offs_y));
        pPassTFChromatix->a3_t2_offs_c                = static_cast<PARAM_UINT>(
            IQSettingUtils::RoundFLOAT(pPassUnpackedData->a3_t2_offs_c));

        pPassTFChromatix->a2_min_y                    = static_cast<PARAM_UINT>(
            IQSettingUtils::RoundFLOAT(pPassUnpackedData->a2_min_y));
        pPassTFChromatix->a2_max_y                    = static_cast<PARAM_UINT>(
            IQSettingUtils::RoundFLOAT(pPassUnpackedData->a2_max_y));
        pPassTFChromatix->a2_min_c                    = static_cast<PARAM_UINT>(
            IQSettingUtils::RoundFLOAT(pPassUnpackedData->a2_min_c));
        pPassTFChromatix->a2_max_c                    = static_cast<PARAM_UINT>(
            IQSettingUtils::RoundFLOAT(pPassUnpackedData->a2_max_c));
        pPassTFChromatix->a2_slope_y                  = static_cast<PARAM_UINT>(
            IQSettingUtils::RoundFLOAT(pPassUnpackedData->a2_slope_y));
        pPassTFChromatix->a2_slope_c                  = static_cast<PARAM_UINT>(
            IQSettingUtils::RoundFLOAT(pPassUnpackedData->a2_slope_c));
        for (idx = 0; idx < 16; idx++)
        {
            pPassTFChromatix->lnr_lut_y[idx] = static_cast<PARAM_UINT>(
                IQSettingUtils::RoundFLOAT(pPassUnpackedData->lnr_lut_y_tab.lnr_lut_y[idx]));
            pPassTFChromatix->lnr_lut_c[idx] = static_cast<PARAM_UINT>(
                IQSettingUtils::RoundFLOAT(pPassUnpackedData->lnr_lut_c_tab.lnr_lut_c[idx]));
        }
        pPassTFChromatix->padding_by_reflection_override = pPassReserveData->padding_by_reflection_override;
        pPassTFChromatix->is_anr_strength_blender_mode   = pPassReserveData->is_anr_strength_blender_mode;

        // ANR final blender parameters
        pPassTFChromatix->anr_final_blender_luma_min_strength_high_freq   = static_cast<PARAM_UINT>(
            IQSettingUtils::RoundFLOAT(pPassUnpackedData->anr_final_blender_luma_min_strength_high_freq));
        pPassTFChromatix->anr_final_blender_luma_min_strength_low_freq    = static_cast<PARAM_UINT>(
            IQSettingUtils::RoundFLOAT(pPassUnpackedData->anr_final_blender_luma_min_strength_low_freq));
        pPassTFChromatix->anr_final_blender_chroma_min_strength_high_freq = static_cast<PARAM_UINT>(
            IQSettingUtils::RoundFLOAT(pPassUnpackedData->anr_final_blender_chroma_min_strength_high_freq));
        pPassTFChromatix->anr_final_blender_chroma_min_strength_low_freq  = static_cast<PARAM_UINT>(
            IQSettingUtils::RoundFLOAT(pPassUnpackedData->anr_final_blender_chroma_min_strength_low_freq));
        pPassTFChromatix->anr_final_blender_strength_decision_ythr_low    = static_cast<PARAM_UINT>(
            IQSettingUtils::RoundFLOAT(pPassUnpackedData->anr_final_blender_strength_decision_ythr_low));
        pPassTFChromatix->anr_final_blender_strength_decision_ythr_high   = static_cast<PARAM_UINT>(
            IQSettingUtils::RoundFLOAT(pPassUnpackedData->anr_final_blender_strength_decision_ythr_high));
        pPassTFChromatix->anr_final_blender_strength_decision_cthr_low    = static_cast<PARAM_UINT>(
            IQSettingUtils::RoundFLOAT(pPassUnpackedData->anr_final_blender_strength_decision_cthr_low));
        pPassTFChromatix->anr_final_blender_strength_decision_cthr_high   = static_cast<PARAM_UINT>(
            IQSettingUtils::RoundFLOAT(pPassUnpackedData->anr_final_blender_strength_decision_cthr_high));
    }
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// TF10Setting::CopyTFFwParamsToPcsimRegs
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
VOID TF10Setting::CopyTFFwParamsToPcsimRegs(
    TfPassParameters*         pFwStructTf,
    RefinementPassParameters* pFwStructRefinement,
    TF_REG*                   pRegStruct,
    UINT                      passType,
    EIPEConfigOption          tfConfigOption)
{
    pRegStruct->en = pFwStructTf->moduleCfg.EN;

    if (TRUE == pRegStruct->en)
    {
        pRegStruct->invalidMctfpImage        = pFwStructTf->invalidMctfpImage;
        pRegStruct->disableOutputIndications = pFwStructTf->disableOutputIndications;
        pRegStruct->useIndications           = !pFwStructTf->disableUseIndications;
        pRegStruct->smearInputsForDecisions  = pFwStructTf->smearInputsForDecisions;
        pRegStruct->useAnrForDecisions_Y     = pFwStructTf->useAnrForDecisions_Y;
        pRegStruct->useAnrForDecisions_C     = pFwStructTf->useAnrForDecisions_C;

        pRegStruct->enableLNR                       = pFwStructTf->enableLNR;
        pRegStruct->enableNoiseEstByLuma            = pFwStructTf->enableNoiseEstByLuma;
        pRegStruct->enableNoiseEstByChroma          = pFwStructTf->enableNoiseEstByChroma;
        pRegStruct->paddingByReflection             = pFwStructTf->paddingByReflection;
        pRegStruct->sadYCalcMode                    = static_cast<FIELD_UINT>(pFwStructTf->sadYCalcMode);
        pRegStruct->isSadC5x3                       = pFwStructTf->isSadC5x3;
        pRegStruct->LnrLutShiftY                    = pFwStructTf->lnrLutShiftY;
        pRegStruct->LnrLutShiftC                    = pFwStructTf->lnrLutShiftC;
        pRegStruct->isDCI                           = pFwStructTf->isDCI;
        pRegStruct->indicationsDominateFsDecision   = pFwStructTf->indicationsDominateFsDecision;
        pRegStruct->applyFsRankFilter               = pFwStructTf->applyFsRankFilter;
        pRegStruct->applyFsLpf                      = pFwStructTf->applyFsLpf;
        pRegStruct->takeOofIndFrom                  = pFwStructTf->takeOofIndFrom;
        pRegStruct->isSameBlendingForAllFrequencies = pFwStructTf->isSameBlendingForAllFrequencies;
        pRegStruct->fsDecisionFreeParamShiftY       = pFwStructTf->fsDecisionFreeParamShiftY;
        pRegStruct->fsDecisionFreeParamShiftC       = pFwStructTf->fsDecisionFreeParamShiftC;
        pRegStruct->outOfFramePixelsConfidence      = pFwStructTf->outOfFramePixelsConfidence;

        pRegStruct->disableLumaGhostDetection     = pFwStructTf->disableLumaGhostDetection;
        pRegStruct->disableChromaGhostDetection   = pFwStructTf->disableChromaGhostDetection;

        pRegStruct->blendingMode                  = pFwStructTf->blendingMode;
        pRegStruct->indicationsDecreaseFactor     = pFwStructTf->indicationsDecreaseFactor;
        if (0 == pFwStructTf->enableIndicationsDecreaseFactor)
        {
            pRegStruct->indicationsDecreaseFactor = 16;
        }
        pRegStruct->invertTemporalBlendingWeights = pFwStructTf->invertTemporalBlendingWeights;
        pRegStruct->ditherY                       = pFwStructTf->ditherY;
        pRegStruct->ditherCb                      = pFwStructTf->ditherCb;
        pRegStruct->ditherCr                      = pFwStructTf->ditherCr;
        pRegStruct->useAnroAsImgInput             = pFwStructTf->useAnroAsImgInput;
        pRegStruct->useImgAsMctfpInput            = pFwStructTf->useImgAsMctfpInput;

        if (pFwStructTf->morphErode == TF_IND_MORPHOLOGY_5x5 ||
            pFwStructTf->morphErode == TF_IND_MORPHOLOGY_3x3)
        {
            pRegStruct->morph_Erode_En = 1;
            pRegStruct->Morph_Erode_Size = pFwStructTf->morphErode;
        }
        else
        {
            pRegStruct->morph_Erode_En = 0;
            pRegStruct->Morph_Erode_Size = 0;
        }

        if (pFwStructTf->morphDilate == TF_IND_MORPHOLOGY_5x5 ||
            pFwStructTf->morphDilate == TF_IND_MORPHOLOGY_3x3)
        {
            pRegStruct->morph_Dilate_En = 1;
            pRegStruct->Morph_Dilate_Size = pFwStructTf->morphDilate;
        }
        else
        {
            pRegStruct->morph_Dilate_En = 0;
            pRegStruct->Morph_Dilate_Size = 0;
        }

        pRegStruct->prngSeed                      = pFwStructTf->prngSeed;

        if (TRUE == pRegStruct->enableLNR)
        {
            pRegStruct->LnrStartIdxH = pFwStructTf->lnrStartIdxH;
            pRegStruct->LnrStartIdxV = pFwStructTf->lnrStartIdxV;
            pRegStruct->LnrScaleH    = pFwStructTf->lnrScaleH;
            pRegStruct->LnrScaleV    = pFwStructTf->lnrScaleV;
        }

        COPY_ARRAY(pRegStruct->fsToA1MapY, pFwStructTf->fsToA1MapY);
        COPY_ARRAY(pRegStruct->fsToA1MapC, pFwStructTf->fsToA1MapC);
        COPY_ARRAY(pRegStruct->fsToA4MapY, pFwStructTf->fsToA4MapY);
        COPY_ARRAY(pRegStruct->fsToA4MapC, pFwStructTf->fsToA4MapC);

        if ((tfConfigOption != IPE_CONFIG_MF_PRE) &&
            (tfConfigOption != IPE_CONFIG_MF_TEMPORAL))
        {
            pRegStruct->a2SlopeC = pFwStructTf->a2SlopeC;
            pRegStruct->a2SlopeY = pFwStructTf->a2SlopeY;
            pRegStruct->a2MinC = pFwStructTf->a2MinC;
            pRegStruct->a2MinY = pFwStructTf->a2MinY;
        }

        pRegStruct->a2MaxC = pFwStructTf->a2MaxC;
        pRegStruct->a2MaxY = pFwStructTf->a2MaxY;

        if ((NULL != pFwStructRefinement) && pFwStructRefinement->refinementCfg.TRENABLE && (passType > 0))
        {
            CAMX_LOG_VERBOSE(CamxLogGroupPProc, " refinementCfg.TRENABLE %d", pFwStructRefinement->refinementCfg.TRENABLE);
            pRegStruct->trEnable = pFwStructRefinement->refinementCfg.TRENABLE;
            pRegStruct->trDeadZone    = pFwStructRefinement->refinementCfg.TRDEADZONE;
            pRegStruct->trFsThreshold = pFwStructRefinement->refinementCfg.TRFSTHRESHOLD;
            pRegStruct->trBlockSizeY  = pFwStructRefinement->blockSizeY;
            pRegStruct->trStartY      = pFwStructRefinement->offsetY;
            pRegStruct->trBlockNumY   = pFwStructRefinement->blockNumY;
            pRegStruct->trBlockSizeX  = pFwStructRefinement->blockSizeX;
            pRegStruct->trStartX      = pFwStructRefinement->offsetX;
            pRegStruct->trBlockNumX   = pFwStructRefinement->blockNumX;
        }
        else
        {
            // set hard coded valid values
            pRegStruct->trEnable      = 0;
            pRegStruct->trDeadZone    = 0;
            pRegStruct->trFsThreshold = 0;
            pRegStruct->trBlockSizeY  = 32;
            pRegStruct->trStartY      = 0;
            pRegStruct->trBlockNumY   = 1;
            pRegStruct->trBlockSizeX  = 59;
            pRegStruct->trStartX      = 0;
            pRegStruct->trBlockNumX   = 1;
        }
    }
    else
    {
        // To prevent freeze on zoom. Workaround for CAMDVBUG-3314.
        pRegStruct->disableOutputIndications = 1;
    }
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// TF10Setting::CopyUINT32toINT32ArrayWithSize
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
VOID TF10Setting::CopyUINT32toINT32ArrayWithSize(
    INT32*        pDstArrayName,
    const UINT32* pSrcArrayName,
    INT           arraySize)
{
    for (INT lutIter = 0; lutIter < arraySize; lutIter++)
    {
        pDstArrayName[lutIter] = static_cast<INT32>(pSrcArrayName[lutIter]);
    }
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// TF10Setting::CopyINT32toINT32ArrayWithSize
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
VOID TF10Setting::CopyINT32toINT32ArrayWithSize(
    INT32*       pDstArrayName,
    const INT32* pSrcArrayName,
    INT          arraySize)
{
    for (INT lutIter = 0; lutIter < arraySize; lutIter++)
    {
        pDstArrayName[lutIter] = pSrcArrayName[lutIter];
    }
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// TF10Setting::CopyUINT32toUINT8ArrayWithSize
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
VOID TF10Setting::CopyUINT32toUINT8ArrayWithSize(
    UINT8*        pDstArrayName,
    const UINT32* pSrcArrayName,
    INT           arraySize)
{
    for (INT lutIter = 0; lutIter < arraySize; lutIter++)
    {
        pDstArrayName[lutIter] = static_cast<UINT8>(pSrcArrayName[lutIter]);
    }
}
